Skip to content

Conversation

LordOfFrogs
Copy link
Contributor

Adds Laplace and inverse Laplace transforms based on linearity and rule tables. Planned use for solving ODEs.

@codecov-commenter
Copy link

codecov-commenter commented Aug 22, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 84.34926% with 95 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.53%. Comparing base (99fbc36) to head (389b328).
⚠️ Report is 69 commits behind head on master.

Files with missing lines Patch % Lines
src/diffeqs/laplace.jl 53.38% 62 Missing ⚠️
src/diffeqs/diffeqs.jl 89.29% 32 Missing ⚠️
src/diffeqs/diffeq_helpers.jl 98.30% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1590      +/-   ##
==========================================
+ Coverage   80.08%   80.53%   +0.45%     
==========================================
  Files          53       58       +5     
  Lines        5358     5970     +612     
==========================================
+ Hits         4291     4808     +517     
- Misses       1067     1162      +95     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@LordOfFrogs LordOfFrogs marked this pull request as ready for review August 22, 2025 04:14
@LordOfFrogs LordOfFrogs changed the title [WIP] Laplace Transform Laplace Transform Aug 22, 2025
@ChrisRackauckas
Copy link
Member

@AayushSabharwal

Helper function to unwrap derivatives of `f(t)` in `expr` with respect to the differential operator `Dt = Differential(t)`. Returns a tuple `(n, base_expr)`, where `n` is the order of the derivative and `base_expr` is the expression with the derivatives removed. If `expr` does not contain `f(t)` or its derivatives, returns `(0, expr)`.
"""
function unwrap_der(expr, Dt)
reduce_rule = @rule Dt(~x) => ~x
Copy link
Member

@AayushSabharwal AayushSabharwal Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeatedly creating @rule in the recursive call and then matching it is pretty expensive. I'd recommend just doing

function reduce_rule(expr, Dt)
     iscall(expr) && isequal(operation(expr), Dt) ? arguments(expr)[1] : nothing
end

end

# takes into account fractions
function _true_factors(expr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use SymbolicUtils.flatten_fractions to handle nested fractions and then SymbolicUtils.numerators to get the list of factors in the numerator and SymbolicUtils.denominators to get the list of factors in the denominator. Make sure to unwrap everything passed into those functions.

return isequal(expr, 0)
end

function _parse_trig(expr, t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about @rule in a function.

import DomainSets.ClosedInterval

# from https://tutorial.math.lamar.edu/Classes/DE/Laplace_Table.aspx
transform_rules(f, t, F, s) = Symbolics.Chain([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if SymbolicUtils.@cache will play nicely with this. It could save a lot of time considering that this is called recursively. This also applies to the previous comments about @rule in recursive functions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, the laplace function could have a keyword rules = nothing. It then does

if rules === nothing
    rules = transform_rules(f, t, F, s)
end

and passes rules down to recursive calls. Again, this approach works for the similar previous comments and is arguably better than @cache.

# t-derivative rule ((Dt^n)(f(t)) -> s^n*F(s) - s^(n-1)*f(0) - s^(n-2)*f'(0) - ... - f^(n-1)(0))
n, expr = unwrap_der(expr, Dt)
if n != 0 && isequal(expr, f(t))
f0 = Symbolics.variables(:f0, 0:(n-1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use some unicode here to avoid name collisions?

Comment on lines +90 to +91
@variables λ # eigenvalue
v = variables(:v, 1:size(A, 1)) # vector of subscripted variables to represent eigenvector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of these should use unicode to avoid name collisions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants